<template>
  <div
    class="file-item"
    :class="{
      'selected': isSelected,
      'dragging': isDragging
    }"
    :draggable="true"
    @dragstart="onDragStart"
    @dragend="onDragEnd"
    @click="onClick"
    @dblclick="onDoubleClick"
    @contextmenu.prevent="onContextMenu"
    :style="itemStyle"
    @touchstart="onTouchStart"
    @touchend="onTouchEnd"
    @touchmove="onTouchMove"
  >
    <div class="file-icon">
      <SvgIcon :name="fileIcon" :size="32" />
    </div>
    <div class="file-info">
      <div class="file-name" :title="safeFileName">
        <span v-if="!isRenaming">{{ safeFileName }}</span>
        <input
          v-else
          ref="renameInput"
          v-model="newName"
          @blur="finishRename"
          @keyup.enter="finishRename"
          @keyup.esc="cancelRename"
          class="rename-input"
        />
      </div>
      <div class="file-details">
        <span class="file-size">{{ formattedSize }}</span>
        <span class="file-date">{{ formattedDate }}</span>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, nextTick, watch } from 'vue'
import type { FileItem } from '../api/fileService'
import { formatFileSize, formatDate, getFileIcon, sanitizeDisplayName, validateAndCleanInput } from '../utils'
import SvgIcon from './SvgIcon.vue'

interface Props {
  file: FileItem
  isSelected: boolean
  gridSize: number
  isRenaming: boolean
}

interface Emits {
  (e: 'select', file: FileItem, ctrlKey: boolean): void
  (e: 'open', file: FileItem): void
  (e: 'contextmenu', event: MouseEvent, file: FileItem): void
  (e: 'longpress', event: TouchEvent, file: FileItem): void
  (e: 'dragstart', file: FileItem): void
  (e: 'dragend'): void
  (e: 'rename', oldName: string, newName: string): void
  (e: 'cancelRename'): void
}

const props = defineProps<Props>()
const emit = defineEmits<Emits>()

const isDragging = ref(false)
const newName = ref('')
const renameInput = ref<HTMLInputElement>()

// 长按相关
const longPressTimer = ref<ReturnType<typeof setTimeout> | null>(null)
const isLongPressed = ref(false)

// 计算属性
const fileIcon = computed(() => getFileIcon(props.file.name, props.file.type))
const formattedSize = computed(() => formatFileSize(props.file.size))
const formattedDate = computed(() => formatDate(props.file.modified))
// 安全的文件名显示
const safeFileName = computed(() => sanitizeDisplayName(props.file.name))

const itemStyle = computed(() => ({
  width: props.gridSize + 'px',
  height: props.gridSize + 'px'
}))

// 监听重命名状态
watch(() => props.isRenaming, (isRenaming) => {
  if (isRenaming) {
    newName.value = props.file.name
    nextTick(() => {
      renameInput.value?.focus()
      renameInput.value?.select()
    })
  }
})

const onClick = (event: MouseEvent) => {
  emit('select', props.file, event.ctrlKey || event.metaKey)
}

const onDoubleClick = () => {
  emit('open', props.file)
}

const onContextMenu = (event: MouseEvent) => {
  emit('contextmenu', event, props.file)
}

const onDragStart = (event: DragEvent) => {
  isDragging.value = true
  emit('dragstart', props.file)
  
  // 设置拖拽数据
  if (event.dataTransfer) {
    event.dataTransfer.effectAllowed = 'move'
    event.dataTransfer.setData('text/plain', props.file.path)
  }
}

const onDragEnd = () => {
  isDragging.value = false
  emit('dragend')
}

const finishRename = () => {
  if (newName.value.trim() && newName.value !== props.file.name) {
    // 验证并清理用户输入
    const cleanedName = validateAndCleanInput(newName.value.trim(), 255)
    if (cleanedName && cleanedName !== props.file.name) {
      emit('rename', props.file.name, cleanedName)
    } else {
      emit('cancelRename')
    }
  } else {
    emit('cancelRename')
  }
}

const cancelRename = () => {
  emit('cancelRename')
}

// 长按事件处理
const onTouchStart = (event: TouchEvent) => {
  isLongPressed.value = false
  longPressTimer.value = setTimeout(() => {
    isLongPressed.value = true
    emit('longpress', event, props.file)
  }, 500) // 500ms 长按触发
}

const onTouchEnd = () => {
  if (longPressTimer.value) {
    clearTimeout(longPressTimer.value)
    longPressTimer.value = null
  }
}

const onTouchMove = () => {
  if (longPressTimer.value) {
    clearTimeout(longPressTimer.value)
    longPressTimer.value = null
  }
}
</script>

<style lang="less" scoped>
.file-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 12px 8px;
  border-radius: 8px;
  cursor: pointer;
  user-select: none;
  transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
  border: 1px solid transparent;
  background: transparent;
  position: relative;
  
  &::before {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: 8px;
    background: linear-gradient(135deg, rgba(255, 255, 255, 0.8), rgba(255, 255, 255, 0.4));
    opacity: 0;
    transition: opacity 0.2s ease;
    z-index: -1;
  }
  
  &:hover {
    background: #f8fafc;
    border-color: #e2e8f0;
    transform: translateY(-1px);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.04), 
                0 2px 4px rgba(0, 0, 0, 0.02);
    
    &::before {
      opacity: 1;
    }
  }
  
  &.selected {
    background: linear-gradient(135deg, #eff6ff, #f0f9ff);
    border-color: #3b82f6;
    box-shadow: 0 4px 12px rgba(59, 130, 246, 0.1), 
                0 2px 4px rgba(59, 130, 246, 0.06),
                inset 0 1px 0 rgba(255, 255, 255, 0.7);
    
    &::before {
      opacity: 0;
    }
  }
  
  &.dragging {
    opacity: 0.5;
    transform: scale(0.95) rotate(2deg);
    box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
  }
  
  .file-icon {
    font-size: 32px;
    margin-bottom: 8px;
    line-height: 1;
    filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.1));
    transition: transform 0.2s ease;
    display: flex;
    align-items: center;
    justify-content: center;
    height: 32px;
  }
  
  &:hover .file-icon {
    transform: scale(1.05);
  }
  
  .file-info {
    text-align: center;
    width: 100%;
    
    .file-name {
      font-weight: 500;
      font-size: 13px;
      margin-bottom: 4px;
      word-break: break-word;
      line-height: 1.3;
      max-height: 2.6em;
      overflow: hidden;
      color: #1f2937;
      letter-spacing: -0.025em;
      
      .rename-input {
        width: 100%;
        padding: 4px 6px;
        border: 1px solid #3b82f6;
        border-radius: 6px;
        font-size: inherit;
        font-family: inherit;
        font-weight: inherit;
        text-align: center;
        outline: none;
        background: #ffffff;
        box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1),
                    0 2px 4px rgba(0, 0, 0, 0.05);
        transition: all 0.15s ease;
        
        &:focus {
          box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2),
                      0 4px 8px rgba(0, 0, 0, 0.1);
        }
      }
    }
    
    .file-details {
      font-size: 11px;
      color: #6b7280;
      line-height: 1.2;
      font-weight: 400;
      
      .file-size,
      .file-date {
        display: block;
        opacity: 0.8;
      }
      
      .file-date {
        margin-top: 1px;
      }
    }
  }
  
  // 选中状态下的文字颜色调整
  &.selected {
    .file-info {
      .file-name {
        color: #1e40af;
        font-weight: 600;
      }
      
      .file-details {
        color: #3b82f6;
        opacity: 0.9;
      }
    }
  }
}

// 响应式设计
@media (max-width: 768px) {
  .file-item {
    padding: 16px 12px;
    min-height: 80px;
    
    .file-icon {
      font-size: 28px;
      margin-bottom: 6px;
    }
    
    .file-info {
      .file-name {
        font-size: 14px;
        max-height: 3em;
        line-height: 1.4;
        
        .rename-input {
          padding: 6px 8px;
          font-size: 14px;
        }
      }
      
      .file-details {
        font-size: 12px;
        
        .file-date {
          margin-top: 2px;
        }
      }
    }
    
    // 增大触摸区域
    &:hover {
      transform: translateY(-2px);
    }
  }
}

// 更小的移动设备
@media (max-width: 480px) {
  .file-item {
    padding: 12px 8px;
    
    .file-icon {
      font-size: 24px;
    }
    
    .file-info {
      .file-name {
        font-size: 13px;
      }
      
      .file-details {
        font-size: 11px;
      }
    }
  }
}
</style> 